package tt.dz.tcp.socket;

import com.alibaba.fastjson.JSON;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import tt.dz.service.imp.middleware.MessageAnalysisHelper;
import tt.dz.service.imp.middleware.instruction.Ev3c2Instructions;
import tt.dz.service.imp.middleware.instruction.Ev3cInstructions;
import tt.dz.service.imp.middleware.instruction.Instruction;
import tt.dz.service.imp.middleware.instruction.InstructionType;
import tt.dz.service.imp.middleware.vo.ProtocolVersion;
import tt.dz.service.imp.middleware.vo.UnSendingMessage;
import tt.dz.tcp.socket.exception.DuplicateInstructionException;
import tt.dz.util.RedisClient;

import java.util.Date;
import java.util.List;

/**
 * Created by luoyp on 2016/6/12.
 * 将发送的报文保存在redis中, 独立的桩号有独立的key, 只保存服务器主动下发的报文, 服务器回复报文不保存
 */
@Component
public class MessageStorage
{
	private Log log = LogFactory.getLog(MessageStorage.class);

	private Jedis jedis;

	public void store(String message, String chargerId) throws DuplicateInstructionException
	{
		String key = "unsendmsg_" + chargerId;
		UnSendingMessage msg = MessageAnalysisHelper.analyseSendingMessage(message, chargerId);
		msg.setCreateDt(new Date());
		if (isValidToBeAdded(msg, key))
		{
			String json = JSON.toJSONString(msg);
			log.info(chargerId);
			log.info(json);
			getJedisClient().rpush(key, json);
		}
//		closeJedisClient();
	}

	private Jedis getJedisClient()
	{
		if (jedis == null)
			jedis = RedisClient.getConnect();
		return jedis;
	}

	private void closeJedisClient()
	{
		if (jedis != null)
			jedis.close();
	}

	/**
	 * 阻止相同的指令重复下发
	 */
	private boolean isValidToBeAdded(UnSendingMessage msg, String key) throws DuplicateInstructionException
	{
		String command = msg.getCommand();
		Instruction instruction;
		if (msg.getProtocolVersion() == ProtocolVersion.Version_2)
		{
			instruction = Ev3c2Instructions.parse(command);
			return instruction.type() == InstructionType.SendByServer;
		}
		else if (msg.getProtocolVersion() == ProtocolVersion.Version_1)
		{
			instruction = Ev3cInstructions.parse(command);
			boolean valid = instruction.type() == InstructionType.SendByServer;

			if (valid)
			{
				List<String> list_msg = getJedisClient().lrange(key, 0, -1);
				for (String s : list_msg)
				{
					UnSendingMessage m = JSON.parseObject(s, UnSendingMessage.class);
					if (m.getCommand().equals(msg.getCommand()))
						throw new DuplicateInstructionException(String.format("Same instruction(%1$s) is pending for sending, charger Id is %2$s", m.getCommand(), m.getChargerId()));
				}
			}
			return valid;
		}
		else
			return false;
	}
}
